package com.vehiclemanagement.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vehiclemanagement.entity.Vehicle;
import com.vehiclemanagement.entity.VehicleInspection;
import com.vehiclemanagement.mapper.VehicleInspectionMapper;
import com.vehiclemanagement.mapper.VehicleMapper;
import com.vehiclemanagement.service.VehicleInspectionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.Year;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 车辆年检记录服务实现类
 */
@Service
@Slf4j
public class VehicleInspectionServiceImpl extends ServiceImpl<VehicleInspectionMapper, VehicleInspection> implements VehicleInspectionService {

    @Autowired
    private VehicleMapper vehicleMapper;

    @Override
    public IPage<VehicleInspection> pageInspections(Integer current, Integer size, String searchTerm,
                                              Long vehicleId, Integer inspectionType, Integer inspectionResult, Integer status,
                                              LocalDateTime startTime, LocalDateTime endTime) {
        log.info("分页查询年检记录: current={}, size={}, searchTerm={}, vehicleId={}, inspectionType={}, inspectionResult={}, status={}, startTime={}, endTime={}",
                current, size, searchTerm, vehicleId, inspectionType, inspectionResult, status, startTime, endTime);
                
        Page<VehicleInspection> page = new Page<>(current, size);
        
        // 构建查询条件
        StringBuilder whereSql = new StringBuilder();
        whereSql.append(" i.del_flag = 0 ");
        
        // 添加搜索条件
        if (StringUtils.hasText(searchTerm)) {
            whereSql.append(" AND (v.plate_number LIKE '%").append(searchTerm).append("%'")
                    .append(" OR i.inspection_location LIKE '%").append(searchTerm).append("%'")
                    .append(" OR i.inspection_company LIKE '%").append(searchTerm).append("%'")
                    .append(" OR i.responsible_person LIKE '%").append(searchTerm).append("%'")
                    .append(" OR i.certificate_number LIKE '%").append(searchTerm).append("%')");
        }
        
        // 添加车辆ID查询条件
        if (vehicleId != null) {
            whereSql.append(" AND i.vehicle_id = ").append(vehicleId);
        }
        
        // 添加年检类型查询条件
        if (inspectionType != null) {
            whereSql.append(" AND i.inspection_type = ").append(inspectionType);
        }
        
        // 添加年检结果查询条件
        if (inspectionResult != null) {
            whereSql.append(" AND i.inspection_result = ").append(inspectionResult);
        }
        
        // 添加状态查询条件
        if (status != null) {
            whereSql.append(" AND i.status = ").append(status);
        }
        
        // 添加时间范围查询条件
        if (startTime != null) {
            whereSql.append(" AND i.inspection_date >= '").append(startTime).append("'");
        }
        
        if (endTime != null) {
            whereSql.append(" AND i.inspection_date <= '").append(endTime).append("'");
        }
        
        try {
            return baseMapper.selectPageWithInfo(page, whereSql.toString());
        } catch (Exception e) {
            log.error("分页查询年检记录失败", e);
            return new Page<>();
        }
    }

    @Override
    public VehicleInspection getInspectionById(Long id) {
        log.info("根据ID获取年检记录: id={}", id);
        
        if (id == null) {
            log.error("获取年检记录失败：ID为空");
            return null;
        }
        
        try {
            // 构建查询条件
            String whereSql = " i.id = " + id + " AND i.del_flag = 0";
            Page<VehicleInspection> page = new Page<>(1, 1);
            IPage<VehicleInspection> recordPage = baseMapper.selectPageWithInfo(page, whereSql);
            
            if (recordPage.getRecords().isEmpty()) {
                log.warn("未找到ID为{}的年检记录", id);
                return null;
            }
            
            return recordPage.getRecords().get(0);
        } catch (Exception e) {
            log.error("获取年检记录失败: id={}", id, e);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addInspection(VehicleInspection inspection) {
        log.info("添加年检记录: {}", inspection);
        
        if (inspection == null) {
            log.error("添加年检记录失败：记录为空");
            return false;
        }
        
        try {
            // 设置默认值
            LocalDateTime now = LocalDateTime.now();
            inspection.setCreateTime(now);
            inspection.setUpdateTime(now);
            inspection.setDelFlag(0);
            
            // 如果状态为空，设置为未开始(0)
            if (inspection.getStatus() == null) {
                inspection.setStatus(0);
            }
            
            // 设置年检里程为当前车辆里程（如果未设置）
            if (inspection.getInspectionMileage() == null && inspection.getVehicleId() != null) {
                Vehicle vehicle = vehicleMapper.selectById(inspection.getVehicleId());
                if (vehicle != null && vehicle.getCurrentMileage() != null) {
                    inspection.setInspectionMileage(vehicle.getCurrentMileage().doubleValue());
                }
            }
            
            // 如果年检费用为空，设置为0
            if (inspection.getInspectionCost() == null) {
                inspection.setInspectionCost(BigDecimal.ZERO);
            }
            
            // 保存记录
            boolean result = save(inspection);
            
            // 如果状态为进行中，更新车辆状态为维修中
            if (result && inspection.getStatus() != null && inspection.getStatus() == 1 && inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 2); // 2=维修中
            }
            
            return result;
        } catch (Exception e) {
            log.error("添加年检记录失败", e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInspection(VehicleInspection inspection) {
        log.info("更新年检记录: {}", inspection);
        
        if (inspection == null || inspection.getId() == null) {
            log.error("更新年检记录失败：记录为空或ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            VehicleInspection originalInspection = getById(inspection.getId());
            if (originalInspection == null) {
                log.error("更新年检记录失败：找不到ID为{}的记录", inspection.getId());
                return false;
            }
            
            // 更新时间
            inspection.setUpdateTime(LocalDateTime.now());
            
            // 更新记录
            boolean result = updateById(inspection);
            
            // 如果状态从其他状态变更为进行中，更新车辆状态为维修中
            if (result && inspection.getStatus() != null && inspection.getStatus() == 1 && 
                (originalInspection.getStatus() == null || originalInspection.getStatus() != 1) && 
                inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 2); // 2=维修中
            }
            
            // 如果状态从进行中变更为已完成，更新车辆状态为空闲
            if (result && inspection.getStatus() != null && inspection.getStatus() == 2 && 
                originalInspection.getStatus() != null && originalInspection.getStatus() == 1 && 
                inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 0); // 0=空闲
            }
            
            return result;
        } catch (Exception e) {
            log.error("更新年检记录失败: id={}", inspection.getId(), e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteInspection(Long id) {
        log.info("删除年检记录: id={}", id);
        
        if (id == null) {
            log.error("删除年检记录失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            VehicleInspection inspection = getById(id);
            if (inspection == null) {
                log.error("删除年检记录失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 如果记录状态为进行中，需要恢复车辆状态为空闲
            if (inspection.getStatus() != null && inspection.getStatus() == 1 && inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 0); // 0=空闲
            }
            
            // 逻辑删除
            inspection.setDelFlag(1);
            inspection.setUpdateTime(LocalDateTime.now());
            
            return updateById(inspection);
        } catch (Exception e) {
            log.error("删除年检记录失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startInspection(Long id) {
        log.info("开始年检: id={}", id);
        
        if (id == null) {
            log.error("开始年检失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            VehicleInspection inspection = getById(id);
            if (inspection == null) {
                log.error("开始年检失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 检查状态是否为未开始
            if (inspection.getStatus() != null && inspection.getStatus() != 0) {
                log.error("开始年检失败：记录状态不是'未开始'，当前状态={}", inspection.getStatus());
                return false;
            }
            
            // 更新记录状态为进行中
            inspection.setStatus(1);
            inspection.setUpdateTime(LocalDateTime.now());
            
            boolean result = updateById(inspection);
            
            // 更新车辆状态为维修中
            if (result && inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 2); // 2=维修中
            }
            
            return result;
        } catch (Exception e) {
            log.error("开始年检失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeInspection(Long id, LocalDateTime inspectionDate, BigDecimal inspectionCost, 
                                   Integer inspectionResult, String failReason, LocalDateTime validStartDate, 
                                   LocalDateTime validEndDate, String certificateNumber, String remark) {
        log.info("完成年检: id={}, inspectionDate={}, inspectionCost={}, inspectionResult={}, failReason={}, validStartDate={}, validEndDate={}, certificateNumber={}, remark={}",
                id, inspectionDate, inspectionCost, inspectionResult, failReason, validStartDate, validEndDate, certificateNumber, remark);
        
        if (id == null) {
            log.error("完成年检失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            VehicleInspection inspection = getById(id);
            if (inspection == null) {
                log.error("完成年检失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 检查状态是否为进行中
            if (inspection.getStatus() == null || inspection.getStatus() != 1) {
                log.error("完成年检失败：记录状态不是'进行中'，当前状态={}", inspection.getStatus());
                return false;
            }
            
            // 设置年检日期，如果未提供则使用当前时间
            inspection.setInspectionDate(inspectionDate != null ? inspectionDate : LocalDateTime.now());
            
            // 设置年检费用
            inspection.setInspectionCost(inspectionCost != null ? inspectionCost : BigDecimal.ZERO);
            
            // 设置年检结果
            inspection.setInspectionResult(inspectionResult != null ? inspectionResult : 1); // 默认通过
            
            // 如果不通过，设置不通过原因
            if (inspectionResult != null && inspectionResult == 2) {
                inspection.setFailReason(failReason);
            }
            
            // 设置有效期
            inspection.setValidStartDate(validStartDate);
            inspection.setValidEndDate(validEndDate);
            
            // 设置证书编号
            inspection.setCertificateNumber(certificateNumber);
            
            // 设置备注
            if (StringUtils.hasText(remark)) {
                inspection.setRemark(remark);
            }
            
            // 更新状态为已完成
            inspection.setStatus(2);
            inspection.setUpdateTime(LocalDateTime.now());
            
            // 如果通过并且有效期结束日期有值，设置下次年检提醒日期
            if (inspection.getInspectionResult() != null && inspection.getInspectionResult() == 1 && validEndDate != null) {
                // 设置为有效期结束前30天
                inspection.setNextReminderDate(validEndDate.minusDays(30));
            }
            
            boolean result = updateById(inspection);
            
            // 更新车辆状态为空闲
            if (result && inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 0); // 0=空闲
            }
            
            return result;
        } catch (Exception e) {
            log.error("完成年检失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelInspection(Long id, String remark) {
        log.info("取消年检: id={}, remark={}", id, remark);
        
        if (id == null) {
            log.error("取消年检失败：ID为空");
            return false;
        }
        
        try {
            // 获取原记录
            VehicleInspection inspection = getById(id);
            if (inspection == null) {
                log.error("取消年检失败：找不到ID为{}的记录", id);
                return false;
            }
            
            // 检查状态是否为未开始或进行中
            if (inspection.getStatus() == null || inspection.getStatus() > 1) {
                log.error("取消年检失败：记录状态不是'未开始'或'进行中'，当前状态={}", inspection.getStatus());
                return false;
            }
            
            // 设置备注
            if (StringUtils.hasText(remark)) {
                inspection.setRemark(remark);
            }
            
            // 更新状态为已取消
            inspection.setStatus(3);
            inspection.setUpdateTime(LocalDateTime.now());
            
            boolean result = updateById(inspection);
            
            // 如果是从进行中状态取消，需要更新车辆状态为空闲
            if (result && inspection.getStatus() == 1 && inspection.getVehicleId() != null) {
                updateVehicleStatus(inspection.getVehicleId(), 0); // 0=空闲
            }
            
            return result;
        } catch (Exception e) {
            log.error("取消年检失败: id={}", id, e);
            throw e; // 抛出异常以触发事务回滚
        }
    }

    @Override
    public BigDecimal sumInspectionCostByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("获取车辆年检总费用失败：车辆ID为空");
            return BigDecimal.ZERO;
        }
        
        try {
            BigDecimal totalCost = baseMapper.sumInspectionCostByVehicleId(vehicleId);
            return totalCost != null ? totalCost : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("获取车辆年检总费用失败: vehicleId={}", vehicleId, e);
            return BigDecimal.ZERO;
        }
    }

    @Override
    public Integer countInspectionByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("获取车辆年检次数失败：车辆ID为空");
            return 0;
        }
        
        try {
            Integer count = baseMapper.countInspectionByVehicleId(vehicleId);
            return count != null ? count : 0;
        } catch (Exception e) {
            log.error("获取车辆年检次数失败: vehicleId={}", vehicleId, e);
            return 0;
        }
    }

    @Override
    public List<Map<String, Object>> statisticsByType(LocalDateTime startTime, LocalDateTime endTime) {
        log.info("按年检类型统计: startTime={}, endTime={}", startTime, endTime);
        
        try {
            // 如果未提供时间范围，使用当前年份
            if (startTime == null || endTime == null) {
                int currentYear = Year.now().getValue();
                startTime = LocalDateTime.of(currentYear, 1, 1, 0, 0, 0);
                endTime = LocalDateTime.of(currentYear, 12, 31, 23, 59, 59);
            }
            
            // 获取统计数据
            List<Map<String, Object>> result = baseMapper.statisticsByType(startTime, endTime);
            
            // 添加年检类型名称
            for (Map<String, Object> item : result) {
                Integer type = (Integer) item.get("inspection_type");
                item.put("inspection_type_name", getInspectionTypeName(type));
            }
            
            return result;
        } catch (Exception e) {
            log.error("按年检类型统计失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, Object>> statisticsByMonth(Integer year) {
        log.info("按月份统计年检费用: year={}", year);
        
        try {
            // 如果未提供年份，使用当前年份
            if (year == null) {
                year = Year.now().getValue();
            }
            
            // 获取统计数据
            return baseMapper.statisticsByMonth(year);
        } catch (Exception e) {
            log.error("按月份统计年检费用失败: year={}", year, e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, Object>> findVehiclesNeedingInspection(Integer daysThreshold) {
        log.info("查询即将到期需要年检的车辆: daysThreshold={}", daysThreshold);
        
        try {
            // 如果未提供天数阈值，使用默认值30天
            if (daysThreshold == null || daysThreshold <= 0) {
                daysThreshold = 30;
            }
            
            // 查询需要年检的车辆
            return baseMapper.findVehiclesNeedingInspection(daysThreshold);
        } catch (Exception e) {
            log.error("查询即将到期需要年检的车辆失败: daysThreshold={}", daysThreshold, e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 更新车辆状态
     *
     * @param vehicleId 车辆ID
     * @param status    状态：0-空闲，1-使用中，2-维修中
     * @return 是否成功
     */
    private boolean updateVehicleStatus(Long vehicleId, Integer status) {
        if (vehicleId == null || status == null) {
            return false;
        }
        
        try {
            Vehicle vehicle = vehicleMapper.selectById(vehicleId);
            if (vehicle == null) {
                log.error("更新车辆状态失败：找不到ID为{}的车辆", vehicleId);
                return false;
            }
            
            vehicle.setStatus(status);
            vehicle.setUpdateTime(LocalDateTime.now());
            
            return vehicleMapper.updateById(vehicle) > 0;
        } catch (Exception e) {
            log.error("更新车辆状态失败: vehicleId={}, status={}", vehicleId, status, e);
            return false;
        }
    }
    
    /**
     * 获取年检类型名称
     *
     * @param type 年检类型
     * @return 年检类型名称
     */
    private String getInspectionTypeName(Integer type) {
        if (type == null) {
            return "未知类型";
        }
        
        switch (type) {
            case 1: return "定期检查";
            case 2: return "年检";
            case 3: return "环保检测";
            case 4: return "综合检测";
            default: return "未知类型";
        }
    }
} 